package com.bob.web.common.config;

import com.bob.web.common.shiro.MyShiroRealm;
import com.bob.web.common.shiro.credentials.RetryLimitHashedCredentialsMatcher;
import com.bob.web.common.shiro.filter.ShiroResourceFilter;
import com.bob.web.common.spring.SpringCacheManagerWrapper;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authc.credential.SimpleCredentialsMatcher;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.session.mgt.DefaultSessionManager;
import org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO;
import org.apache.shiro.session.mgt.eis.JavaUuidSessionIdGenerator;
import org.apache.shiro.session.mgt.quartz.QuartzSessionValidationScheduler;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.cache.ehcache.EhCacheCacheManager;
import org.springframework.cache.ehcache.EhCacheManagerFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;

import java.util.LinkedHashMap;

/**
 * 名称: ShiroConfiguration<br>
 * 描述:<br>
 * 类型: JAVA<br>
 * 最近修改时间:2017/7/14 14:09<br>
 *
 * @author BoYangsh
 * @version [版本号, V1.0]
 * @since 2017/7/14 14:09
 */
@Configuration
public class ShiroConfiguration {

	//配置生命周期的
	@Bean
	public LifecycleBeanPostProcessor lifecycleBeanPostProcessor(){
		return new LifecycleBeanPostProcessor();
	}


	//读取ehcache配置文件
	@Bean
	public EhCacheManagerFactoryBean ehCacheManagerFactoryBean() {
		EhCacheManagerFactoryBean ehCacheManagerFactoryBean = new EhCacheManagerFactoryBean();
		ehCacheManagerFactoryBean.setConfigLocation(new ClassPathResource("ehcache.xml")); //如果不配置，就是默认
		return ehCacheManagerFactoryBean;
	}

	/**
	 * ehcache缓存管理器
	 * @param ehCacheManagerFactoryBean
	 * @return
	 */
	@Bean
	public EhCacheCacheManager ehCacheCacheManager( EhCacheManagerFactoryBean ehCacheManagerFactoryBean) {
		EhCacheCacheManager ehCacheCacheManager = new EhCacheCacheManager();
		ehCacheCacheManager.setCacheManager(ehCacheManagerFactoryBean.getObject());
		return ehCacheCacheManager;
	}

	/**
	 * 包装Spring cache抽象
	 * @param ehCacheCacheManager
	 * @return
	 */
	@Bean
	public CacheManager cacheManager(EhCacheCacheManager ehCacheCacheManager) {
		SpringCacheManagerWrapper springCacheManagerWrapper = new SpringCacheManagerWrapper();
		springCacheManagerWrapper.setCacheManager(ehCacheCacheManager);
		return springCacheManagerWrapper;
	}

//	<!--shiro缓存管理器 -->
//	<bean id="cacheManager" class="com.oneday.ashop.console.base.shiro.spring.SpringCacheManagerWrapper" >
//	<property name="cacheManager" ref="springCacheManager"/>
//	</bean>




	//配置自定义的密码比较器(这里选择的是默认的密码比较)
	@Bean
	public RetryLimitHashedCredentialsMatcher credentialsMatcher(CacheManager cacheManager) {
		RetryLimitHashedCredentialsMatcher hashedCredentialsMatcher =  new RetryLimitHashedCredentialsMatcher(cacheManager);
		hashedCredentialsMatcher.setHashAlgorithmName("md5");
		hashedCredentialsMatcher.setHashIterations(2); //默认是1
		hashedCredentialsMatcher.setStoredCredentialsHexEncoded(true);
		return hashedCredentialsMatcher;
	}

//		@Bean
//		public SimpleCredentialsMatcher credentialsMatcher() {
//			SimpleCredentialsMatcher simpleCredentialsMatcher =  new SimpleCredentialsMatcher();
//			return simpleCredentialsMatcher;
//		}




	//代理
	@Bean
	public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator(){
		DefaultAdvisorAutoProxyCreator creator=new DefaultAdvisorAutoProxyCreator();
		creator.setProxyTargetClass(true);
		return creator;
	}

	//配置自定义的权限登录器
	@Bean
	public MyShiroRealm authRealm( CredentialsMatcher matcher, CacheManager cacheManager) {
		MyShiroRealm authRealm = new MyShiroRealm();
		authRealm.setCredentialsMatcher(matcher); //凭证
		authRealm.setAuthenticationCacheName("authenticationCache"); //这个是缓存认证信息的key，和ehcache.xml中配置要一致
		authRealm.setAuthorizationCacheName("authorizationCache"); //这个是缓存授权信息的key，和ehcache.xml中配置要一致
		//这条配置一定要在上面两条配置之后，不然上面的两个key的设置是没有用的
		authRealm.setCacheManager(cacheManager);
		return authRealm;
	}

	//配置核心安全事务管理器
	@Bean
	public DefaultWebSecurityManager securityManager( MyShiroRealm myShiroRealm, CacheManager cacheManager, DefaultSessionManager defaultSessionManager) {
		System.err.println("--------------shiro已经加载----------------");
		DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
		manager.setRealm(myShiroRealm);
		manager.setCacheManager(cacheManager);
		manager.setSessionManager(defaultSessionManager);
		return manager;
	}

	//spring整合shiro凭证匹配器
	@Bean
	public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager manager) {
		AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
		advisor.setSecurityManager(manager);
		return advisor;
	}

	@Bean
	public ShiroFilterFactoryBean shiroFilter( DefaultWebSecurityManager manager, ShiroResourceFilter shiroResourceFilter) {
		ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
		bean.setSecurityManager(manager);
		bean.getFilters().put("shiroResourceFilter", shiroResourceFilter);
		//配置登录的url和登录成功的url
		bean.setLoginUrl("/no_login"); //未登录时，跳转的请求
//		bean.setSuccessUrl("/home");
		//配置访问权限
		LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
//		filterChainDefinitionMap.put("/jsp/login.jsp*", "anon"); //表示可以匿名访问
//		filterChainDefinitionMap.put("/loginUser", "anon");
//		filterChainDefinitionMap.put("/user/login","anon");
//		filterChainDefinitionMap.put("/error","anon");
//		filterChainDefinitionMap.put("/logout*","anon");
//		filterChainDefinitionMap.put("/jsp/error.jsp*","anon");
//		filterChainDefinitionMap.put("/jsp/index.jsp*","authc");
	;
//		filterChainDefinitionMap.put("/user/info", "authc");//表示需要认证才可以访问
		filterChainDefinitionMap.put("/*", "authc");//表示需要认证才可以访问
		filterChainDefinitionMap.put("/**", "shiroResourceFilter");//表示需要认证才可以访问
//		filterChainDefinitionMap.put("/*.*", "authc");
		bean.setFilterChainDefinitionMap(filterChainDefinitionMap);
		return bean;
	}

	/**
	 * 会话ID生成器
	 * @return
	 */
	@Bean
	public JavaUuidSessionIdGenerator javaUuidSessionIdGenerator() {
		return new JavaUuidSessionIdGenerator();
	}

	/**
	 *  会话DAO
	 * @param javaUuidSessionIdGenerator
	 * @return
	 */
	@Bean
	public EnterpriseCacheSessionDAO enterpriseCacheSessionDAO(JavaUuidSessionIdGenerator javaUuidSessionIdGenerator) {
		EnterpriseCacheSessionDAO enterpriseCacheSessionDAO = new EnterpriseCacheSessionDAO();
		enterpriseCacheSessionDAO.setSessionIdGenerator(javaUuidSessionIdGenerator);
		//这个默认就是这个，不配置也是可以
		enterpriseCacheSessionDAO.setActiveSessionsCacheName(EnterpriseCacheSessionDAO.ACTIVE_SESSION_CACHE_NAME);
		return enterpriseCacheSessionDAO;
	}

	/**
	 * 会话管理器
	 * @return
	 */
	@Bean
	DefaultSessionManager defaultSessionManager(EnterpriseCacheSessionDAO enterpriseCacheSessionDAO, QuartzSessionValidationScheduler quartzSessionValidationScheduler) {
		DefaultSessionManager defaultSessionManager = new DefaultSessionManager();
		defaultSessionManager.setGlobalSessionTimeout(1800000);
		defaultSessionManager.setSessionValidationScheduler(quartzSessionValidationScheduler);
		defaultSessionManager.setDeleteInvalidSessions(true);
		defaultSessionManager.setSessionValidationSchedulerEnabled(true);
		defaultSessionManager.setSessionDAO(enterpriseCacheSessionDAO);
		return defaultSessionManager;
	}

	@Bean
	public QuartzSessionValidationScheduler quartzSessionValidationScheduler() {
		QuartzSessionValidationScheduler quartzSessionValidationScheduler = new QuartzSessionValidationScheduler();
//		quartzSessionValidationScheduler.setSessionManager(defaultSessionManager);
		quartzSessionValidationScheduler.setSessionValidationInterval(1800000);
		return quartzSessionValidationScheduler;
	}

	/**
	 * 资源过滤器
	 * @return
	 */
	@Bean
	public ShiroResourceFilter shiroResourceFilter() {
		ShiroResourceFilter shiroResourceFilter = new ShiroResourceFilter();
//		shiroResourceFilter.init();
		return shiroResourceFilter;
	}



}
